﻿using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Windows;
using System.Windows.Input;
using Labthink.PCSoft.UniversalHost4.DataAccess;
using Labthink.PCSoft.UniversalHost4.Model.User;
using Labthink.PCSoft.UniversalHost4.UserControls;
using Labthink.PCSoft.UniversalHost4.UserControls.MsgBox;
using Labthink.PCSoft.UniversalHost4.Utility;

namespace Labthink.PCSoft.UniversalHost4
{
    public partial class AddRole
    {
        private int _roleId;

        private readonly string _successMsg = LanguageManager.GetLanguageValue("ActionSuccess");

        public string ActionMsg { get; set; }

        public int RoleId
        {
            get => _roleId;
            set
            {
                _roleId = value;
                TxtTitle.Text = LanguageManager.GetLanguageValue("ModifyRoleWindowTitle");
            }
        }

        private Window _owner;

        public AddRole()
        {
            InitializeComponent();
        }

        private void Window_Loaded(object sender, RoutedEventArgs e)
        {
            _owner = GetWindow(this);
            if (_roleId > 0) LoadAuthoritiesTreeByRoleId();
            else LoadAuthoritiesTree();
        }

        private void LoadAuthoritiesTree()
        {
            _triggerButtonsStatus(false);

            List<Permission> permissions = RoleAndPerRepository.GetAllPermissions();
            ObservableCollection<TreeNodeModel> treeSource = ConstructTree(permissions, null);
            if (treeSource != null)
            {
                cbtPermissions.ItemsSourceData = treeSource;
                cbtPermissions.RefreshCheckStatus();
            }

            _triggerButtonsStatus(true);
        }

        private ObservableCollection<TreeNodeModel> ConstructTree(IReadOnlyCollection<Permission> permissions, TreeNodeModel parentNode)
        {
            if (null == parentNode)
            {
                parentNode = new TreeNodeModel();
                parentNode.Code = "";
            }

            foreach (Permission permission in permissions)
            {
                if (parentNode.Code == permission.ParentId)
                {
                    var node = new TreeNodeModel(parentNode);

                    node.Id = permission.Id + "";
                    node.Code = permission.Code;
                    node.Name = permission.NameCn;
                    node.IsExpanded = true;

                    if (permissions.Count > 0)
                    {
                        ConstructTree(permissions, node);
                    }
                }
            }

            if (parentNode.Code != "")
            {
                return null;
            }

            var treeList = new ObservableCollection<TreeNodeModel>();
            foreach (TreeNodeModel node in parentNode.Children)
            {
                treeList.Add(node);
            }

            return treeList;
        }

        private void LoadAuthoritiesTreeByRoleId()
        {
            _triggerButtonsStatus(false);

            var roleInfo = RoleAndPerRepository.GetRole(_roleId);
            txtRoleName.Value = roleInfo.RoleName;
            txtRoleName.IsEnabled = false;

            var treeSource = ConstructTreeByRoleId(roleInfo.Pers, null);
            if (treeSource != null)
            {
                cbtPermissions.ItemsSourceData = treeSource;
                cbtPermissions.RefreshCheckStatus();
            }

            _triggerButtonsStatus(true);
        }

        private static ObservableCollection<TreeNodeModel> ConstructTreeByRoleId(IReadOnlyCollection<PerInfo> permissions, TreeNodeModel parentNode)
        {
            parentNode ??= new TreeNodeModel
            {
                Code = ""
            };

            foreach (PerInfo permission in permissions)
            {
                if (parentNode.Code == permission.Parentid)
                {
                    var node = new TreeNodeModel(parentNode)
                    {
                        Name = permission.Name,
                        Id = permission.Pid,
                        Code = permission.Code,
                        IsChecked = permission.Checked,
                        IsExpanded = true
                    };

                    if (permissions.Count > 0)
                    {
                        ConstructTreeByRoleId(permissions, node);
                    }
                }
            }

            if (parentNode.Code != "")
            {
                return null;
            }

            var treeList = new ObservableCollection<TreeNodeModel>();
            foreach (TreeNodeModel node in parentNode.Children)
            {
                treeList.Add(node);
            }

            return treeList;
        }

        private void btnOK_Click(object sender, RoutedEventArgs e)
        {
            txtRoleName.Txt_OnLostFocus(null, null);
            if (string.IsNullOrEmpty(txtRoleName.Value.Trim()))
            {
                MyMessageBox.Show(_owner, LanguageManager.GetLanguageValue("DataEmpty_RoleName"));
                return;
            }

            _triggerButtonsStatus(false);

            if (_roleId > 0)
            {
                var ris = new RoleInfoSimple
                {
                    RoleId = _roleId,
                    RoleName = txtRoleName.Value,
                    Pers = new List<string>()
                };

                var checkedItems = cbtPermissions.GetCheckedItems();
                foreach (TreeNodeModel node in checkedItems)
                {
                    ris.Pers.Add(node.Code);
                }

                try
                {
                    RoleAndPerRepository.MergeRole(ris);
                    LogRepository.AddLog(LanguageManager.GetLanguageValue("OP-RoleUpdate", ris.RoleName), "Manage");
                    ActionMsg = _successMsg;
                    DialogResult = true;
                    Close();
                }
                catch (Exception ex)
                {
                    MyMessageBox.Show(_owner, ex.Message);
                }
            }
            else
            {
                bool r = RoleAndPerRepository.Exists(txtRoleName.Value.Trim());
                if (r)
                {
                    string msg = LanguageManager.GetLanguageValue("NameExist_RoleName", txtRoleName.Value.Trim());
                    MyMessageBox.Show(_owner, msg);
                    _triggerButtonsStatus(true);
                    return;
                }

                var ris = new RoleInfoSimple
                {
                    RoleName = txtRoleName.Value,
                    Pers = new List<string>()
                };

                ObservableCollection<TreeNodeModel> checkedItems = cbtPermissions.GetCheckedItems();
                foreach (TreeNodeModel node in checkedItems)
                {
                    ris.Pers.Add(node.Code);
                }

                try
                {
                    RoleAndPerRepository.AddRole(ris);
                    LogRepository.AddLog(LanguageManager.GetLanguageValue("OP-RoleAdd", ris.RoleName), "Manage");
                    ActionMsg = _successMsg;
                    DialogResult = true;
                    Close();
                }
                catch (Exception ex)
                {
                    MyMessageBox.Show(_owner, ex.Message);
                }
            }

            _triggerButtonsStatus(true);
        }

        private void btnCancel_Click(object sender, RoutedEventArgs e)
        {
            Close();
        }

        private void _triggerButtonsStatus(bool status)
        {
            btnOK.IsEnabled = status;
            btnCancel.IsEnabled = status;
            Loading.Visibility = status ? Visibility.Collapsed : Visibility.Visible;
        }

        //private string GetIds(IList<TreeNodeModel> treeList)
        //{
        //    var ids = new StringBuilder();

        //    foreach (TreeNodeModel tree in treeList)
        //    {
        //        ids.Append(tree.Id).Append(",");
        //    }

        //    return ids.ToString();
        //}

        private void Window_MouseDown(object sender, MouseButtonEventArgs e)
        {
            if (e.LeftButton == MouseButtonState.Pressed) DragMove();
        }

        private void ButtonBase_OnClick(object sender, RoutedEventArgs e)
        {
            Close();
        }
    }
}
